<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>11.天空盒</title>
</head>

<body>
	<canvas id="canvas"></canvas>
	<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/primitives.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/texture-utils.js"></script>
	<script src="https://webglfundamentals.org/webgl/resources/chroma.min.js"></script>
	<script type="x-shader/x-vertex" id="vertex">
		attribute vec4 a_position;
		attribute vec4 a_normal;
		
		varying vec4 v_normal;
		varying vec4 v_position;
		void main(){
			gl_Position =  a_position;
			v_position = a_position;
  			gl_Position.z = 1.0;
		}
	</script>
	<script type="x-shader/x-fragment" id="fragment">
		precision mediump float;
		
		uniform mat4 u_viewDirectionProjectionInverse;
		uniform samplerCube u_texture;
		varying vec4 v_normal;
		varying vec4 v_position;
		void main() {
			vec4 t = u_viewDirectionProjectionInverse * v_position;//使用透视和投影的逆矩阵计算当前显示的位置
		  	gl_FragColor =  textureCube(u_texture, normalize(t.xyz / t.w));
		}
	</script>
	<script>
		const canvas = document.getElementById("canvas");
		canvas.width = window.innerWidth
		canvas.height = window.innerHeight
		const gl = canvas.getContext("webgl")
		const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
		const programInfo = webglUtils.createProgramInfo(gl, ["vertex", "fragment"])
		let program = programInfo.program
		const planeBufferInfo = primitives.createCubeBufferInfo(
			gl,
			20
		);
		const quadBufferInfo = primitives.createXYQuadBufferInfo(gl);

		gl.useProgram(programInfo.program)
		function degToRad(d) {
			return d * Math.PI / 180;
		}

		var texture = gl.createTexture();
		gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
		const images = [
			{target: gl.TEXTURE_CUBE_MAP_POSITIVE_X, image: new Image, src: "/pos-x.jpg"},
			{target: gl.TEXTURE_CUBE_MAP_NEGATIVE_X, image: new Image, src: "/neg-x.jpg"},
			{target: gl.TEXTURE_CUBE_MAP_POSITIVE_Y, image: new Image, src: "/pos-y.jpg"},
			{target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, image: new Image, src: "/neg-y.jpg"},
			{target: gl.TEXTURE_CUBE_MAP_POSITIVE_Z, image: new Image, src: "/pos-z.jpg"},
			{target: gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, image: new Image, src: "/neg-z.jpg"},
		];
		const arrs = []
		images.forEach((i) => {
			gl.texImage2D(i.target, 0, gl.RGBA, 512, 512, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
			i.image.onload = (e => {
				gl.texImage2D(i.target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, i.image);
			})
			i.image.src = i.src
		})

		gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
		gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);

		function draw(time) {
    		time *= 0.001;
			var cameraPosition = [Math.cos(time * .1), 0, Math.sin(time * .1)];
			const cameraMatrix = m4.lookAt(cameraPosition, [0, 0, 0], [0, 1, 0])
			const viewMatrix = m4.inverse(cameraMatrix)
			viewMatrix[12] = 0;
			viewMatrix[13] = 0;
			viewMatrix[14] = 0;
			const projectionMatrix = m4.perspective(degToRad(60), aspect, 1, 2000);
			const pv = m4.multiply(projectionMatrix, viewMatrix)
			var viewDirectionProjectionInverseMatrix = m4.inverse(pv);
			gl.enable(gl.CULL_FACE);
			gl.enable(gl.DEPTH_TEST);
			gl.depthFunc(gl.LEQUAL);
			gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
			webglUtils.setBuffersAndAttributes(gl, programInfo, quadBufferInfo);
			webglUtils.setUniforms(programInfo, {
				u_viewDirectionProjectionInverse: viewDirectionProjectionInverseMatrix,
				u_texture: texture,
			});
			webglUtils.drawBufferInfo(gl, quadBufferInfo);
			requestAnimationFrame(draw);
		}
		requestAnimationFrame(draw);
	</script>
</body>

</html>